 /*******************************************************************************
  * Copyright (c) 2000, 2006 IBM Corporation and others.
  * All rights reserved. This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License v1.0
  * which accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
  * Contributors:
  * IBM Corporation - initial API and implementation
  *******************************************************************************/

 package org.eclipse.ui.internal.activities;

 import java.io.IOException ;
 import java.util.ArrayList ;
 import java.util.Collections ;
 import java.util.List ;

 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
 import org.eclipse.core.runtime.IExtensionDelta;
 import org.eclipse.core.runtime.IExtensionRegistry;
 import org.eclipse.core.runtime.IRegistryChangeEvent;
 import org.eclipse.core.runtime.IRegistryChangeListener;
 import org.eclipse.ui.internal.util.ConfigurationElementMemento;

 final class ExtensionActivityRegistry extends AbstractActivityRegistry {
     private List activityRequirementBindingDefinitions;

     private List activityDefinitions;

     private List activityPatternBindingDefinitions;

     private List categoryActivityBindingDefinitions;

     private List categoryDefinitions;

     private List defaultEnabledActivities;

     private IExtensionRegistry extensionRegistry;

     ExtensionActivityRegistry(IExtensionRegistry extensionRegistry) {
         if (extensionRegistry == null) {
             throw new NullPointerException ();
         }

         this.extensionRegistry = extensionRegistry;

         this.extensionRegistry
                 .addRegistryChangeListener(new IRegistryChangeListener() {
                     public void registryChanged(
                             IRegistryChangeEvent registryChangeEvent) {
                         IExtensionDelta[] extensionDeltas = registryChangeEvent
                                 .getExtensionDeltas(Persistence.PACKAGE_PREFIX,
                                         Persistence.PACKAGE_BASE);

                         if (extensionDeltas.length != 0) {
                             try {
                                 load();
                             } catch (IOException eIO) {
                             }
                         }
                     }
                 });

         try {
             load();
         } catch (IOException eIO) {
         }
     }

     private String getNamespace(IConfigurationElement configurationElement) {
         String namespace = null;

         if (configurationElement != null) {
             IExtension extension = configurationElement.getDeclaringExtension();

             if (extension != null) {
                 namespace = extension.getNamespace();
             }
         }

         return namespace;
     }

     private void load() throws IOException {
         if (activityRequirementBindingDefinitions == null) {
             activityRequirementBindingDefinitions = new ArrayList ();
         } else {
             activityRequirementBindingDefinitions.clear();
         }

         if (activityDefinitions == null) {
             activityDefinitions = new ArrayList ();
         } else {
             activityDefinitions.clear();
         }

         if (activityPatternBindingDefinitions == null) {
             activityPatternBindingDefinitions = new ArrayList ();
         } else {
             activityPatternBindingDefinitions.clear();
         }

         if (categoryActivityBindingDefinitions == null) {
             categoryActivityBindingDefinitions = new ArrayList ();
         } else {
             categoryActivityBindingDefinitions.clear();
         }

         if (categoryDefinitions == null) {
             categoryDefinitions = new ArrayList ();
         } else {
             categoryDefinitions.clear();
         }

         if (defaultEnabledActivities == null) {
             defaultEnabledActivities = new ArrayList ();
         } else {
             defaultEnabledActivities.clear();
         }

         IConfigurationElement[] configurationElements = extensionRegistry
                 .getConfigurationElementsFor(Persistence.PACKAGE_FULL);

         for (int i = 0; i < configurationElements.length; i++) {
             IConfigurationElement configurationElement = configurationElements[i];
             String name = configurationElement.getName();

             if (Persistence.TAG_ACTIVITY_REQUIREMENT_BINDING.equals(name)) {
                 readActivityRequirementBindingDefinition(configurationElement);
             } else if (Persistence.TAG_ACTIVITY.equals(name)) {
                 readActivityDefinition(configurationElement);
             } else if (Persistence.TAG_ACTIVITY_PATTERN_BINDING.equals(name)) {
                 readActivityPatternBindingDefinition(configurationElement);
             } else if (Persistence.TAG_CATEGORY_ACTIVITY_BINDING.equals(name)) {
                 readCategoryActivityBindingDefinition(configurationElement);
             } else if (Persistence.TAG_CATEGORY.equals(name)) {
                 readCategoryDefinition(configurationElement);
             } else if (Persistence.TAG_DEFAULT_ENABLEMENT.equals(name)) {
                 readDefaultEnablement(configurationElement);
             }
         }

         boolean activityRegistryChanged = false;

         if (!activityRequirementBindingDefinitions
                 .equals(super.activityRequirementBindingDefinitions)) {
             super.activityRequirementBindingDefinitions = Collections
                     .unmodifiableList(activityRequirementBindingDefinitions);
             activityRegistryChanged = true;
         }

         if (!activityDefinitions.equals(super.activityDefinitions)) {
             super.activityDefinitions = Collections
                     .unmodifiableList(activityDefinitions);
             activityRegistryChanged = true;
         }

         if (!activityPatternBindingDefinitions
                 .equals(super.activityPatternBindingDefinitions)) {
             super.activityPatternBindingDefinitions = Collections
                     .unmodifiableList(activityPatternBindingDefinitions);
             activityRegistryChanged = true;
         }

         if (!categoryActivityBindingDefinitions
                 .equals(super.categoryActivityBindingDefinitions)) {
             super.categoryActivityBindingDefinitions = Collections
                     .unmodifiableList(categoryActivityBindingDefinitions);
             activityRegistryChanged = true;
         }

         if (!categoryDefinitions.equals(super.categoryDefinitions)) {
             super.categoryDefinitions = Collections
                     .unmodifiableList(categoryDefinitions);
             activityRegistryChanged = true;
         }

         if (!defaultEnabledActivities.equals(super.defaultEnabledActivities)) {
             super.defaultEnabledActivities = Collections
                     .unmodifiableList(defaultEnabledActivities);
             activityRegistryChanged = true;
         }

         if (activityRegistryChanged) {
             fireActivityRegistryChanged();
         }
     }

     private void readDefaultEnablement(
             IConfigurationElement configurationElement) {
         String enabledActivity = Persistence
                 .readDefaultEnablement(new ConfigurationElementMemento(
                         configurationElement));

         if (enabledActivity != null) {
             defaultEnabledActivities.add(enabledActivity);
         }

     }

     private void readActivityRequirementBindingDefinition(
             IConfigurationElement configurationElement) {
         ActivityRequirementBindingDefinition activityRequirementBindingDefinition = Persistence
                 .readActivityRequirementBindingDefinition(
                         new ConfigurationElementMemento(configurationElement),
                         getNamespace(configurationElement));

         if (activityRequirementBindingDefinition != null) {
             activityRequirementBindingDefinitions
                     .add(activityRequirementBindingDefinition);
         }
     }

     private void readActivityDefinition(
             IConfigurationElement configurationElement) {
         ActivityDefinition activityDefinition = Persistence
                 .readActivityDefinition(new ConfigurationElementMemento(
                         configurationElement),
                         getNamespace(configurationElement));

         if (activityDefinition != null) {
             activityDefinitions.add(activityDefinition);
         }
     }

     private void readActivityPatternBindingDefinition(
             IConfigurationElement configurationElement) {
         ActivityPatternBindingDefinition activityPatternBindingDefinition = Persistence
                 .readActivityPatternBindingDefinition(
                         new ConfigurationElementMemento(configurationElement),
                         getNamespace(configurationElement));

         if (activityPatternBindingDefinition != null) {
             activityPatternBindingDefinitions
                     .add(activityPatternBindingDefinition);
         }
     }

     private void readCategoryActivityBindingDefinition(
             IConfigurationElement configurationElement) {
         CategoryActivityBindingDefinition categoryActivityBindingDefinition = Persistence
                 .readCategoryActivityBindingDefinition(
                         new ConfigurationElementMemento(configurationElement),
                         getNamespace(configurationElement));

         if (categoryActivityBindingDefinition != null) {
             categoryActivityBindingDefinitions
                     .add(categoryActivityBindingDefinition);
         }
     }

     private void readCategoryDefinition(
             IConfigurationElement configurationElement) {
         CategoryDefinition categoryDefinition = Persistence
                 .readCategoryDefinition(new ConfigurationElementMemento(
                         configurationElement),
                         getNamespace(configurationElement));

         if (categoryDefinition != null) {
             categoryDefinitions.add(categoryDefinition);
         }
     }
 }

